// scripts/generate_rpc_handlers.ts
import fs from "fs";
import yaml from "js-yaml";
import path from "path";
import { fileURLToPath } from "url";

// Get the directory name in ESM
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

async function generateRpcHandlers() {
  const dartHandlerYamlFilePath = path.resolve(
    __dirname,
    "ext.dart.handler.yaml"
  );
  const flutterHandlerYamlFilePath = path.resolve(
    __dirname,
    "ext.flutter.handler.yaml"
  );

  const generatedFilePath = path.resolve(
    __dirname,
    "..",
    "src",
    "tools",
    "flutter_rpc_handlers.generated.ts"
  );

  try {
    const dartHandlerYamlContent = fs.readFileSync(
      dartHandlerYamlFilePath,
      "utf8"
    );
    const flutterHandlerYamlContent = fs.readFileSync(
      flutterHandlerYamlFilePath,
      "utf8"
    );
    const dartHandlerConfig = yaml.load(dartHandlerYamlContent) as {
      handlers: any[];
    };
    const flutterHandlerConfig = yaml.load(flutterHandlerYamlContent) as {
      handlers: any[];
    };
    const handlers = [
      ...dartHandlerConfig.handlers,
      ...flutterHandlerConfig.handlers,
    ];

    // Generate the config map
    let configMapCode = `
export const rpcToolConfigs = {
${handlers
  .map(
    (handler) => `  ${handler.name}: {
    rpcMethod: '${handler.rpcMethod}',
    needsDebugVerification: ${handler.needsDebugVerification === true},
    needsDartProxy: ${handler.needsDartServiceExtensionProxy === true}
  }`
  )
  .join(",\n")}
} as const;

export type RpcToolName = keyof typeof rpcToolConfigs;
`;

    // Generate the handler class
    let handlerClassCode = `
import { RpcToolResponseType, RpcUtilities } from "../servers/rpc_utilities.js";

/**
 * Generated class containing handlers for Flutter RPC tools.
 *
 * This class is generated from server_tools_handler.yaml.
 * Do not edit this file directly.
 */
export class FlutterRpcHandlers {
  constructor(
    private rpcUtils: RpcUtilities,
    private handlePortParam: (request: any) => number
  ) {}

  async handleToolRequest(toolName: RpcToolName, request: any): Promise<RpcToolResponseType> {
    const config = rpcToolConfigs[toolName];
    if (!config) throw new Error(\`Invalid tool request: \${toolName}\`);
    
    const port = this.handlePortParam(request);
    const params = request?.params?.arguments;

    if (config.needsDebugVerification) {
      await this.rpcUtils.verifyFlutterDebugMode(port);
    }

    const result = await this.rpcUtils.callDartVm({
          method: config.rpcMethod,
          dartVmPort: port,
          params,
        });

    return this.rpcUtils.wrapResponse(Promise.resolve(result));
  }
}
`;

    // Write the generated files
    fs.writeFileSync(generatedFilePath, configMapCode + handlerClassCode);

    console.log(`Generated FlutterRpcHandlers class at: ${generatedFilePath}`);
  } catch (error) {
    console.error("Error generating RPC handlers:", error);
  }
}

generateRpcHandlers();
